﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;

namespace FTI.SP.LADM.EnhancedContentQueryWebPart.Exslt
{
    public sealed class ExsltSets
    {
        // Fields
        private static ExsltSets _Instance;

        // Methods
        private ExsltSets()
        {
        }

        public static XPathNodeIterator Difference(XPathNodeIterator nodeSet1, XPathNodeIterator nodeSet2)
        {
            ExsltNodeList list = new ExsltNodeList(nodeSet1, true);
            ExsltNodeList list2 = new ExsltNodeList(nodeSet2);
            for (int i = 0; i < list.Count; i++)
            {
                XPathNavigator navigator = list[i];
                if (list2.Contains(navigator))
                {
                    list.RemoveAt(i);
                    i--;
                }
            }
            return ExsltCommon.ExsltNodeListToXPathNodeIterator(list);
        }

        public static XPathNodeIterator Distinct(XPathNodeIterator nodeSet)
        {
            ExsltNodeList list = new ExsltNodeList();
            while (nodeSet.MoveNext())
            {
                if (!list.ContainsValue(nodeSet.Current.Value))
                {
                    list.Add(nodeSet.Current.Clone());
                }
            }
            return ExsltCommon.ExsltNodeListToXPathNodeIterator(list);
        }

        public static bool HasSameNode(XPathNodeIterator nodeSet1, XPathNodeIterator nodeSet2)
        {
            ExsltNodeList list = new ExsltNodeList(nodeSet1, true);
            ExsltNodeList list2 = new ExsltNodeList(nodeSet2, true);
            foreach (XPathNavigator navigator in list)
            {
                if (list2.Contains(navigator))
                {
                    return true;
                }
            }
            return false;
        }

        public static XPathNodeIterator Intersection(XPathNodeIterator nodeSet1, XPathNodeIterator nodeSet2)
        {
            ExsltNodeList list = new ExsltNodeList(nodeSet1, true);
            ExsltNodeList list2 = new ExsltNodeList(nodeSet2);
            for (int i = 0; i < list.Count; i++)
            {
                XPathNavigator navigator = list[i];
                if (!list2.Contains(navigator))
                {
                    list.RemoveAt(i);
                    i--;
                }
            }
            return ExsltCommon.ExsltNodeListToXPathNodeIterator(list);
        }

        public static XPathNodeIterator Leading(XPathNodeIterator nodeSet1, XPathNodeIterator nodeSet2)
        {
            XPathNavigator nav = null;
            if (nodeSet2.MoveNext())
            {
                nav = nodeSet2.Current;
            }
            else
            {
                return nodeSet1;
            }
            ExsltNodeList list = new ExsltNodeList();
            while (nodeSet1.MoveNext())
            {
                if (nodeSet1.Current.ComparePosition(nav) == XmlNodeOrder.Before)
                {
                    list.Add(nodeSet1.Current.Clone());
                }
            }
            return ExsltCommon.ExsltNodeListToXPathNodeIterator(list);
        }

        public static bool Subset(XPathNodeIterator nodeSet1, XPathNodeIterator nodeSet2)
        {
            ExsltNodeList list = new ExsltNodeList(nodeSet1, true);
            ExsltNodeList list2 = new ExsltNodeList(nodeSet2, true);
            foreach (XPathNavigator navigator in list)
            {
                if (!list2.Contains(navigator))
                {
                    return false;
                }
            }
            return true;
        }

        public static XPathNodeIterator Trailing(XPathNodeIterator nodeSet1, XPathNodeIterator nodeSet2)
        {
            XPathNavigator nav = null;
            if (nodeSet2.MoveNext())
            {
                nav = nodeSet2.Current;
            }
            else
            {
                return nodeSet1;
            }
            ExsltNodeList list = new ExsltNodeList();
            while (nodeSet1.MoveNext())
            {
                if (nodeSet1.Current.ComparePosition(nav) == XmlNodeOrder.After)
                {
                    list.Add(nodeSet1.Current.Clone());
                }
            }
            return ExsltCommon.ExsltNodeListToXPathNodeIterator(list);
        }

        // Properties
        public static ExsltSets Instance
        {
            get
            {
                if (_Instance == null)
                {
                    _Instance = new ExsltSets();
                }
                return _Instance;
            }
        }

    }
}
